package com.zyg.filter;

import com.alibaba.fastjson.JSON;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.zyg.common.RedisKey;
import com.zyg.common.ResultCode;
import com.zyg.common.UnInterceptUrl;
import com.zyg.model.Result;
import com.zyg.model.UserInfo;
import com.zyg.util.UserInfoUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 网关拦截器，对请求进行过滤
 */
@Slf4j
@Component
public class TokenFilter extends ZuulFilter {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public String filterType() {
        // 登录校验，肯定是在前置拦截
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        // 该常量值为5 ，减1后为4
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        // 返回true，代表过滤器生效。
        return true;
    }

    @SneakyThrows
    @Override
    public Object run(){
        // 登录校验逻辑。
        // 1）获取Zuul提供的请求上下文对象
        RequestContext ctx = RequestContext.getCurrentContext();//RequestContext是一个Request域，此域的作用范围是从请求到达zuul一直到路由结束返回到客户端，整个完整流程都会存在
        // 2) 从上下文中获取request对象
        HttpServletRequest req = ctx.getRequest();
        log.info("请求>>  -----");
        log.info("请求的 IP：{}",req.getRemoteAddr());
        log.info("请求的 URL：{}",req.getRequestURI());
        log.info("请求的 方式：{}",req.getMethod());

        //放行，不过滤的接口
        if(UnInterceptUrl.getUnInterceptUrl().contains(req.getRequestURI())){
            return null;
        }

        //获取用户信息
        UserInfo userInfo = UserInfoUtil.getUserSaveInfo();
        if(userInfo != null){
            //2--->验证是否在redis中
            if(redisTemplate.opsForValue().get(RedisKey.PC_USER_TOKEN_INFO+userInfo.getUserId()) != null){
                //3--->通过
                return null;
            }
            else {
                // 没有token，登录校验失败，拦截
                ctx.setSendZuulResponse(false);//true则放行，false则拦截
                //构造拦截的返回值
                Result result = new Result().initCodeAndMsg(ResultCode.INVALID_TOKEN);
                String resultJson = JSON.toJSONString(result);
                HttpServletResponse response = ctx.getResponse();
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setHeader("Access-Control-Allow-Headers", "*");
                response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
                response.setHeader("Access-Control-Allow-Credentials","true");
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                ctx.setResponse(response);
                ctx.setResponseBody(resultJson);
            }
        }
        else {
            // 没有token，登录校验失败，拦截
            ctx.setSendZuulResponse(false);//true则放行，false则拦截
            //构造拦截的返回值
            Result result = new Result().initCodeAndMsg(ResultCode.INVALID_TOKEN);
            String resultJson = JSON.toJSONString(result);
            HttpServletResponse response = ctx.getResponse();
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Headers", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Allow-Credentials","true");
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            ctx.setResponse(response);
            ctx.setResponseBody(resultJson);
        }
        return null;//默认为空即为放行
    }
}